{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"../common/rfsoc_book_banner.jpg\" alt=\"University of Strathclyde\" align=\"left\">"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-block\" style=\"background-color: #c7b8d6; padding: 10px\">\n",
    "    <p style=\"color: #222222\">\n",
    "        <b>Note:</b>\n",
    "        <br>\n",
    "        This Jupyter notebook uses hardware features of the Zynq UltraScale+ RFSoC device. Therefore, the notebook cells will only execute successfully on an RFSoC platform.\n",
    "    </p>\n",
    "</div>\n",
    "\n",
    "# Notebook Set A\n",
    "\n",
    "---\n",
    "\n",
    "## 03 - PYNQ Introduction\n",
    "This notebook introduces Python Productivity on Zynq, which is commonly referred to as PYNQ. We begin by describing the PYNQ framework and listing useful documentation and online resources for you to explore. We will then introduce several libraries that are provided alongside PYNQ that are generally used to control and interface to the Programmable Logic (PL) portion of the RFSoC device. Lastly, we will investigate PYNQ Overlays, which are programmmable hardware configurations that are implemented on the PL. \n",
    "\n",
    "## Table of Contents\n",
    "* [1. Introduction](#introduction)\n",
    "* [2. Online Resources](#online-resources)\n",
    "* [3. PYNQ Libraries](#pynq-libraries)\n",
    "* [4. PYNQ Overlays](#pynq-overlays)\n",
    "* [5. Conclusion](#conclusion)\n",
    "\n",
    "## Revision\n",
    "* **v1.0** | 23/01/23 | *First Revision*\n",
    "\n",
    "---\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Introduction <a class=\"anchor\" id=\"introduction\"></a>\n",
    "PYNQ is often described as a software framework for Zynq-base embedded systems that can be conceived as a stack of layers, as shown in Figure 1. The layers include a Programmable Logic (PL) hardware system design, an Operating System (OS) layer, low-level drivers layer for interfacing to the hardware, a Python software layer, and a software application layer. The primary advantage of using PYNQ for embedded system development is that it provides a pre-configured software stack that is complemented by hardware libraries and reusable software components. It is also open-source!\n",
    "\n",
    "<figure>\n",
    "<img src=\"./images/pynq_rfsoc_framework.png\" style=\"width: 60%;\"/>\n",
    "    <figcaption><b>Figure 1: Simplified diagram of the PYNQ framework with RFSoC-PYNQ libraries.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "\n",
    "The software stack shown in Figure 1 also contains RFSoC specific libraries. This particular flavour of PYNQ is referred to as RFSoC-PYNQ. We will explore each of these libraries later in the [RFSoC Radio Notebooks](../notebook_G/01_rfsoc_radio_system.ipynb), and [SD-FEC Notebooks](../notebook_H/01_fec_first_principles.ipynb)."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Online Resources <a class=\"anchor\" id=\"online-resources\"></a>\n",
    "PYNQ is a very well supported project and is complemented by thorough documentation and an excellent community base. Below, we list several online resources that you may find useful as you explore PYNQ on your RFSoC platform.\n",
    "\n",
    "* We begin with the PYNQ website, which is the home of the PYNQ project.\n",
    "    * [PYNQ Website](http://www.pynq.io/)\n",
    "* The source code for the PYNQ project is stored on GitHub.\n",
    "    * [PYNQ Source Code](https://github.com/xilinx/pynq)\n",
    "* The RFSoC-PYNQ project has its own website, where you can keep up-to-date with the latest releases and supported boards.\n",
    "    * [RFSoC-PYNQ Website](https://www.rfsoc-pynq.io/)\n",
    "* All RFSoC-PYNQ supported platforms are stored in a GitHub repository, where you can rebuild base overlay designs if required.\n",
    "    * [RFSoC-PYNQ Source Code](https://github.com/Xilinx/RFSoC-PYNQ)\n",
    "* PYNQ is supported with documentation that you can access from Read The Docs.\n",
    "    * [Read The Docs](https://pynq.readthedocs.io/en/latest/getting_started.html)\n",
    "* Lastly, community support is available from the PYNQ support forums that you can access using the link below.\n",
    "    * [PYNQ Support](https://discuss.pynq.io/)\n",
    "\n",
    "\n",
    "Finally, there are [PYNQ Community Projects](http://www.pynq.io/embedded.html) if you would like to see some of the creative designs that members of the PYNQ community have worked on."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. PYNQ Libraries <a class=\"anchor\" id=\"pynq-libraries\"></a>\n",
    "The PYNQ Python library can be imported like any other Python library, such as NumPy or Pandas. We simply import PYNQ into our Jupyter Notebook using the command below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pynq"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "PYNQ contains a variety of classes and modules that are useful for interfacing to hardware accelerators and interfaces. We can obtain the classes in the PYNQ library and print them for inspection below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from inspect import getmembers, isclass\n",
    "\n",
    "for name, handle in getmembers(pynq, isclass):\n",
    "    print(name)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "PYNQ classes can reduce the amount of software development required by an application. For instance, the Bitstream class can be used to download a bitstream file to the PL. The Interrupt class manages a single interrupt pin in the PL and can be used several times for multiple interrupts. There are also DefaultIP and DefaultHierarchy classes, which significantly reduce software development time when interfacing to the hardware. We will explore these classes in the [next notebook](04_overlays.ipynb).\n",
    "\n",
    "There are several other [PYNQ Libraries](https://pynq.readthedocs.io/en/latest/pynq_libraries.html) for you to explore. We can print these below. Many of them control hardware accelerators or interfaces in the PL."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pynq.lib\n",
    "\n",
    "for name, handle in getmembers(pynq.lib, isclass):\n",
    "    print(name)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. PYNQ Overlays <a class=\"anchor\" id=\"pynq-overlays\"></a>\n",
    "PYNQ overlays [2] extend a Zynq based Processing System (PS) design into the Field Programmable Gate Array (FPGA) logic fabric. Overlays can accelerate a user's software application by exploiting the parallel processing of FPGA architectures. A software engineer is able to use an overlay with ease as FPGA accelerators are abstracted using software libraries (such as those described in the previous section).\n",
    "\n",
    "The PYNQ distribution for your RFSoC development platform has a default base overlay design. We can load it using the code cell below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pynq.overlays.base import BaseOverlay\n",
    "\n",
    "base = BaseOverlay('base.bit')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The BaseOverlay class inherits from the PYNQ Overlay class, which provides parsing tools, descriptors, and bitstream management functionality. The BaseOverlay FPGA design consists of many useful accelerators and interfaces that we can communicate with from JupyterLabs. For example, we can query the status of the RFSoC's Data Converters (RF DCs)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "base.radio.rfdc.IPStatus"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The base overlay design has a huge amount of content that you can access directly from your RFSoC board. From the Jupyter Workspace, navigate to the folder named base. You will be able to see other folders named board, pmod, and rfdc that contain Jupyter Notebooks for you to explore. To get you started, here is a notebook on [buttons, leds, and switches](../../base/board/buttons_leds_switches.ipynb) that you can run. When you are ready, return here to conclude this notebook and move on to the next one."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Conclusion <a class=\"anchor\" id=\"conclusion\"></a>\n",
    "This notebook briefly explored PYNQ and its corresponding documentation, resources, and libraries.\n",
    "\n",
    "The next notebook will demonstrate the operation and hardware interfacing of a simple overlay design in the RFSoC's PL."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "[⬅️ Previous Notebook](02_visualisation_and_analysis.ipynb) || [Next Notebook 🚀](04_overlays.ipynb)\n",
    "\n",
    "Copyright © 2023 Strathclyde Academic Media\n",
    "\n",
    "---\n",
    "---"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
